package com.exonline.front.controller.pay;

import cn.hutool.core.util.IdUtil;
import com.exonline.commons.dao.DaoImpl;
import com.exonline.commons.dao.IDao;
import com.exonline.commons.entity.Courses;
import com.exonline.commons.entity.Order;
import com.exonline.commons.entity.StudentCourses;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;

import java.sql.SQLException;
import java.util.*;

/**
 * @desc  支付的M层
 * @author hbrj
 */
public class PayService {

    // 引入数据访问对象
    IDao<Order>  orderDao = new DaoImpl<>(); //订单的数据访问对象
    IDao<StudentCourses> studentCoursesDao = new DaoImpl<>(); // 学生课程的数据访问对象
    IDao<Courses> coursesIDao = new DaoImpl<>(); //课程的数据访问对象

    /**
     * @desc 1. 根据学生ID查询订单信息，包含关联课程表获取课程名称等信息，并区分待支付和已完成订单
     * @author hbrj
     * @param sid 学生的ID
     * @return 订单信息列表，每个元素是一个包含订单相关字段以及课程名称的Map对象
     * @throws SQLException 如果数据库查询出现异常则抛出此异常
     */
    public List<Map<String, Object>> queryOrdersBySid(String sid, String status) throws SQLException {
        // 1. 构建动态SQL (id,创建时间,状态,课程名,课程价格)
        StringBuilder sqlBuilder = new StringBuilder("SELECT o.id, o.createtime, o.status, c.cname,c.cprice " + "FROM orders o " + "LEFT JOIN courses c ON o.cid = c.id " + "WHERE o.sid =?");
        // 2. 创建参数列表
        List<Object> params = new ArrayList<>();
        params.add(sid);// 添加参数
        // 3. 加状态筛选条件   订单信息状态( 参数:    2:查询全部      1: 已支付       0: 待支付  )
        if (status!= null) {
            // 3.1判断状态
            if ("0".equals(status)) {
                sqlBuilder.append(" AND o.status = 0 ");
            } else if ("1".equals(status)) {
                sqlBuilder.append(" AND o.status = 1 ");
            } else if ("2".equals(status)) {
                // 3.2 当status为2时，不添加额外的针对status的筛选条件，即查询全部状态的订单
            } else {
                throw new IllegalArgumentException(" 无效的状态值, 接受的值为0、1或2 ");
            }
        }
        String sql = sqlBuilder.toString();
        List<Map<String, Object>> orderList = new ArrayList<>(); // 用于存储查询结果
        List<Map<String, Object>> rawOrders = orderDao.queryWithPagingAndConditions(sql, null, 1, 10000, new MapListHandler(), params.toArray());
        // 4. 遍历结果集，将每个订单信息封装成一个Map对象，并将其添加到orderList中
        for (Map<String, Object> rawOrder : rawOrders) {
            // 4.1创建一个Map对象，用于存储订单信息
            Map<String, Object> orderMap = new HashMap<>();
            orderMap.put("id", rawOrder.get("id"));
            // 4.2可以添加更严谨的类型判断，确保createtime字段值能正确处理，这里从结果集中获取时进行类型判断
            Object createTimeObj = rawOrder.get("createtime");
            // 4.3判断是否为Date类型，如果是则添加到orderMap中
            if (createTimeObj!= null && createTimeObj instanceof Date) {
                orderMap.put("createtime", createTimeObj);
            }
            // 4.4添加订单状态和课程名称和课程价格到orderMap中
            orderMap.put("status", rawOrder.get("status"));
            orderMap.put("cname", rawOrder.get("cname"));
            orderMap.put("cprice", rawOrder.get("cprice"));
            orderList.add(orderMap);
        }
        return orderList;
    }

    /**
     * @desc 2.判断指定学生是否已购买指定课程
     * @author hbrj
     * @param sid 学生的ID
     * @param cid 课程的ID
     * @return true表示已购买，false表示未购买
     * @throws SQLException 如果数据库查询出现异常则抛出此异常
     */
    public boolean isCoursePurchased(String sid, String cid) throws SQLException {
        // 1. 构建动态SQL
        String sql = "SELECT status FROM orders WHERE sid =? AND cid =?";
        // 2. 执行查询
        List<Map<String, Object>> resultList = orderDao.queryWithPagingAndConditions(sql, null, 1, 10, new MapListHandler(), sid, cid);
        // 3. 判断查询结果是否为空且不为空列表
        if (resultList != null && !resultList.isEmpty()) {
            Map<String, Object> resultMap = resultList.get(0);
            // 3.1 获取状态字段的值
            Object statusObj = resultMap.get("status");
            // 3.2 判断状态字段是否为空 (添加)
            if (statusObj != null ) {
                return true;
            }
        }
        return false;
    }

    /**
     * @desc 3. 判断指定课程是否为免费课程（即课程价格是否为0）
     * @author hbrj
     * @param cid 课程的ID
     * @return true表示课程价格为0，是免费课程；false表示不是免费课程
     * @throws SQLException 如果数据库查询出现异常则抛出此异常
     */
    public boolean isCourseFree(String cid) throws SQLException {
        // 1. 构建动态SQL
        String sql = "SELECT * FROM courses WHERE id =?";
        // 2. 执行查询
        Courses courses = coursesIDao.queryForObject(sql, new BeanHandler<>(Courses.class), cid);
        // 3. 判断课程价格是否为0,为0执行返回true, 执行addFreeCourseToStudent 把课程添加到学生的个人课程表（studentcourses表, 否则跳转
        if (courses.getCprice().startsWith("0")) {
            return true;
        }
        return false;
    }

    /**
     * @desc 4. 将免费课程添加到学生的个人课程表（studentcourses表）中
     * @author hbrj
     * @param sid 学生的ID
     * @param cid 课程的ID
     * @return true表示添加成功，false表示添加失败
     * @throws SQLException 如果数据库插入操作出现异常则抛出此异常
     */
    public boolean addFreeCourseToStudent(String sid, String cid) throws SQLException {
        // 1. 生成主键id
        String id = IdUtil.simpleUUID();
        // 2. 构建动态SQL
        StringBuilder sqlBuilder = new StringBuilder("INSERT INTO studentcourses (id, sid, cid) VALUES(?,?,?)");
        // 3. 构建参数
        List<Object> params = new ArrayList<>();
        params.add(id);
        params.add(sid);
        params.add(cid);
        // 4. 执行插入操作
        int rowsAffected = studentCoursesDao.updateWithTransaction(sqlBuilder.toString(), params.toArray());
        return rowsAffected > 0;
    }


    public boolean createOrdersForCourses(String sid, List<String> cidList) throws SQLException {
        if (cidList == null || cidList.isEmpty()) {
            // 如果传入的课程ID列表为空，认为不需要创建订单，返回成功
            return true;
        }
        StringBuilder sqlBuilder = new StringBuilder("INSERT INTO orders (id, sid, cid, status) VALUES ");
        List<Object> params = new ArrayList<>();
        List<String> orderIdList = new ArrayList<>();
        for (int i = 0; i < cidList.size(); i++) {
            String orderId = IdUtil.simpleUUID();
            orderIdList.add(orderId);
            // 假设初始订单状态为0（待支付）
            sqlBuilder.append("(?,?,?,0),");
            params.add(orderId);
            params.add(sid);
            params.add(cidList.get(i));
        }
        // 删除最后多余的逗号
        sqlBuilder.deleteCharAt(sqlBuilder.length() - 1);

        int[] rowsAffectedArray = new int[]{orderDao.updateWithTransaction(sqlBuilder.toString(), params.toArray())};
        for (int rows : rowsAffectedArray) {
            if (rows <= 0) {
                // 如果有任何一次插入操作失败（插入的行数小于等于0），则整体返回失败
                return false;
            }
        }
        return true;
    }
}
